//
// Created by ct on 2020/10/10.
//

#include "request_handler.h"
#include <iostream>
#include <string>
#include "mime_types.h"
#include "request.h"
#include "reply.h"
#include "url_parse.h"
#include "router.h"
//#include "nettop_run.h"



namespace http {
    namespace server {
        request_handler::request_handler(std::string doc_root ,const router::node& http_router) :
        doc_root_(std::move(doc_root)),
        http_router_(http_router){}

        void request_handler::handle_request(const request &req, reply &rep) {

            // 解码url到路径。
            std::string request_path;
            if (!request_handler::url_decode(req.uri, request_path)) {
                rep = reply::stock_reply(reply::bad_request);
                return;
            }
            //std::cout << req.uri <<std::endl;
            url_parse::url_result_map ump =  url_parse::parse(req.uri);
//            for(const auto& u : ump){
//                std::cout<< u.first <<  "  " << u.second << std::endl;
//            }

            std::string response = http_router_.handler(ump["router"])(ump);
//----------------------------------------------------------------------------------------------------------
//            std::chrono::system_clock::time_point latest_time = std::chrono::system_clock::now();
//            nettop::proc_mgr p_mgr;
//            nettop::proc_mgr::stats mgr_st;
//            nettop::ps_vec p_vec;
//            sleep(1);
//            const std::chrono::system_clock::time_point cur_time = std::chrono::system_clock::now();
//            std::list<nettop::packet_stats> ps_list;
//            nettop::nettop_mgr::Instance().p_list.swap(ps_list);
//            mgr_st.total_pkts = nettop::nettop_mgr::Instance().p_list.total_pkts.exchange(0);
//            p_mgr.bind_packets(ps_list, nettop::nettop_mgr::Instance().lam, p_vec, mgr_st,
//                               nettop::nettop_mgr::Instance().log_list);
//            // redraw 函数 内部有一个打印函数，这里有需要的信息
//            //  nettop::curses_setup::redraw(cur_time - latest_time, p_vec, mgr_st);
//            auto json_str = nettop::curses_setup::format_proc(cur_time - latest_time, p_vec, mgr_st);
//----------------------------------------------------------------------------------------------------------





            std::string extension = "json";
            rep.content.append(response);
            //rep.content.append(json_str);
            // 添加头信息
            rep.status = reply::ok;
            rep.headers.resize(6);
            rep.headers[0].name = "Content-Length";
            rep.headers[0].value = std::to_string(rep.content.size());
            //rep.headers[0].name = "Access-Control-Allow-Origin";
            //rep.headers[0].value = std::to_string('*');
            rep.headers[1].name = "Content-Type";
            rep.headers[1].value = mime_types::extension_to_type(extension);
            rep.headers[2].name = "Access-Control-Allow-Origin";
            rep.headers[2].value = "*";
            rep.headers[3].name = "Access-Control-Allow-Credentials";
            rep.headers[3].value = "true";
            rep.headers[4].name = "Access-Control-Allow-Headers";
            rep.headers[4].value = "Content-Type,X-Requested-With";
            rep.headers[5].name = "Access-Control-Allow-Methods";
            rep.headers[5].value = "PUT,POST,GET,DELETE,OPTIONS";
        }

        bool request_handler::url_decode(const std::string &in, std::string &out) {
            out.clear();
            out.reserve(in.size());

            for (std::size_t i = 0; i < in.size(); ++i) {
                if (in[i] == '%') {
                    if (i + 3 <= in.size()) {
                        int value = 0;
                        std::istringstream is(in.substr(i + 1, 2));
                        if (is >> std::hex >> value) {
                            out += static_cast<char>(value);
                            i += 2;
                        } else {
                            return false;
                        }
                    } else {
                        return false;
                    }
                } else if (in[i] == '+') {
                    out += ' ';
                } else {
                    out += in[i];
                }
            }
            return true;
        }
    } // namespace server

} // namespace http